/*
 * Copyright (C) 2001-2010 Jacek Sieka, arnetheduck on gmail point com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include "stdafx.h"
#include "../client/DCPlusPlus.h"
#include "Resource.h"

#include "NetworkPage.h"
//[-]PPA [Doxygen 1.5.1] #include "../client/SettingsManager.h"
#include "../client/Socket.h"
#include "WinUtil.h"

//[!]IRainman moved to WinUtils.
//#include <IPHlpApi.h>
//#pragma comment(lib, "iphlpapi.lib")

PropPage::TextItem NetworkPage::texts[] =
{
	{ IDC_CONNECTION_DETECTION, ResourceManager::CONNECTION_DETECTION },
	{ IDC_DIRECT, ResourceManager::SETTINGS_DIRECT },
	{ IDC_FIREWALL_UPNP, ResourceManager::SETTINGS_FIREWALL_UPNP },
	{ IDC_FIREWALL_NAT, ResourceManager::SETTINGS_FIREWALL_NAT },
	{ IDC_FIREWALL_PASSIVE, ResourceManager::SETTINGS_FIREWALL_PASSIVE },
	{ IDC_AUTODETECT, ResourceManager::SETTINGS_CONNECTION_AUTODETECT },
	{ IDC_OVERRIDE, ResourceManager::SETTINGS_OVERRIDE },
	{ IDC_UPDATE_IP_DHT, ResourceManager::SETTINGS_UPDATE_IP },
	{ IDC_SETTINGS_PORTS, ResourceManager::SETTINGS_PORTS },
	{ IDC_SETTINGS_IP, ResourceManager::SETTINGS_EXTERNAL_IP },
	{ IDC_SETTINGS_PORT_TCP, ResourceManager::SETTINGS_TCP_PORT },
	{ IDC_SETTINGS_PORT_UDP, ResourceManager::SETTINGS_UDP_PORT },
	{ IDC_SETTINGS_PORT_TLS, ResourceManager::SETTINGS_TLS_PORT },
	{ IDC_SETTINGS_PORT_DHT, ResourceManager::SETTINGS_DHT_PORT },
	{ IDC_SETTINGS_INCOMING, ResourceManager::SETTINGS_INCOMING },
	{ IDC_SETTINGS_BIND_ADDRESS, ResourceManager::SETTINGS_BIND_ADDRESS },
	{ IDC_SETTINGS_BIND_ADDRESS_HELP, ResourceManager::SETTINGS_BIND_ADDRESS_HELP },
	{ IDC_NATT, ResourceManager::ALLOW_NAT_TRAVERSAL },
	{ IDC_CON_CHECK, ResourceManager::CHECK_SETTINGS },
	{ IDC_IPUPDATE, ResourceManager::UPDATE_IP },
	{ IDC_SETTINGS_UPDATE_IP_INTERVAL, ResourceManager::UPDATE_IP_INTERVAL },
	{ IDC_SETTINGS_USE_DHT,  ResourceManager::USE_DHT },
	{ IDC_GETIP, ResourceManager::GET_IP },
	
	{ 0, ResourceManager::SETTINGS_AUTO_AWAY }
};

PropPage::Item NetworkPage::items[] =
{
	{ IDC_CONNECTION_DETECTION, SettingsManager::AUTO_DETECT_CONNECTION, PropPage::T_BOOL },
	{ IDC_EXTERNAL_IP,      SettingsManager::EXTERNAL_IP,   PropPage::T_STR },
	{ IDC_PORT_TCP,         SettingsManager::TCP_PORT,      PropPage::T_INT },
	{ IDC_PORT_UDP,         SettingsManager::UDP_PORT,      PropPage::T_INT },
	{ IDC_PORT_TLS,         SettingsManager::TLS_PORT,      PropPage::T_INT },
	{ IDC_PORT_DHT,         SettingsManager::DHT_PORT,      PropPage::T_INT },
	{ IDC_OVERRIDE,         SettingsManager::NO_IP_OVERRIDE, PropPage::T_BOOL },
	{ IDC_UPDATE_IP_DHT,    SettingsManager::UPDATE_IP_DHT,     PropPage::T_BOOL },
	{ IDC_IP_GET_IP,        SettingsManager::URL_GET_IP,    PropPage::T_STR }, //[+]PPA
	{ IDC_URL_TEST_IP,      SettingsManager::URL_TEST_IP,   PropPage::T_STR }, //[+]PPA
	{ IDC_IPUPDATE,         SettingsManager::IPUPDATE,      PropPage::T_BOOL },
	{ IDC_UPDATE_IP_INTERVAL, SettingsManager::IPUPDATE_INTERVAL, PropPage::T_INT },
	{ IDC_BIND_ADDRESS,     SettingsManager::BIND_ADDRESS, PropPage::T_STR },
	{ IDC_NATT,             SettingsManager::ALLOW_NAT_TRAVERSAL, PropPage::T_BOOL },
	{ IDC_SETTINGS_USE_DHT, SettingsManager::USE_DHT, PropPage::T_BOOL },
	{ 0, 0, PropPage::T_END }
};

void NetworkPage::write()
{
	PropPage::write((HWND)(*this), items);
	
	// Set connection active/passive
	int ct = SettingsManager::INCOMING_DIRECT;
	
	if (IsDlgButtonChecked(IDC_FIREWALL_UPNP))
		ct = SettingsManager::INCOMING_FIREWALL_UPNP;
	else if (IsDlgButtonChecked(IDC_FIREWALL_NAT))
		ct = SettingsManager::INCOMING_FIREWALL_NAT;
	else if (IsDlgButtonChecked(IDC_FIREWALL_PASSIVE))
		ct = SettingsManager::INCOMING_FIREWALL_PASSIVE;
		
	if (SETTING(INCOMING_CONNECTIONS) != ct)
	{
		settings->set(SettingsManager::INCOMING_CONNECTIONS, ct);
	}
	
#ifdef RIP_USE_CONNECTION_AUTODETECT
	settings->set(SettingsManager::INCOMING_AUTODETECT_FLAG, int(IsDlgButtonChecked(IDC_AUTODETECT)));
#endif
}

LRESULT NetworkPage::onInitDialog(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
{
	PropPage::translate((HWND)(*this), texts);
	
#ifndef PPA_INCLUDE_UPNP
	if (!isOsSupportedThemeAndUPnP())
	{
		::EnableWindow(GetDlgItem(IDC_FIREWALL_UPNP), FALSE); //[+]PPA
	}
#endif
#ifndef IRAINMAN_IP_AUTOUPDATE
	::EnableWindow(GetDlgItem(IDC_GETIP), FALSE);
	::EnableWindow(GetDlgItem(IDC_IPUPDATE), FALSE);
#endif
	
	switch (SETTING(INCOMING_CONNECTIONS))
	{
		case SettingsManager::INCOMING_DIRECT:
			CheckDlgButton(IDC_DIRECT, BST_CHECKED);
			break;
		case SettingsManager::INCOMING_FIREWALL_UPNP:
			CheckDlgButton(IDC_FIREWALL_UPNP, BST_CHECKED);
			break;
		case SettingsManager::INCOMING_FIREWALL_NAT:
			CheckDlgButton(IDC_FIREWALL_NAT, BST_CHECKED);
			break;
		case SettingsManager::INCOMING_FIREWALL_PASSIVE:
			CheckDlgButton(IDC_FIREWALL_PASSIVE, BST_CHECKED);
			break;
		default:
			CheckDlgButton(IDC_DIRECT, BST_CHECKED);
			break;
	}
	
#ifdef RIP_USE_CONNECTION_AUTODETECT
	CheckDlgButton(IDC_AUTODETECT, SETTING(INCOMING_AUTODETECT_FLAG));
#else
	::EnableWindow(GetDlgItem(IDC_AUTODETECT), FALSE);
#endif
	
	PropPage::read((HWND)(*this), items);
	
	fixControls();
	
	desc.Attach(GetDlgItem(IDC_PORT_TCP));
	desc.LimitText(5);
	desc.Detach();
	desc.Attach(GetDlgItem(IDC_PORT_UDP));
	desc.LimitText(5);
	desc.Detach();
	desc.Attach(GetDlgItem(IDC_PORT_TLS));
	desc.LimitText(5);
	desc.Detach();
	desc.Attach(GetDlgItem(IDC_PORT_DHT));
	desc.LimitText(5);
	desc.Detach();
	
	ConnCheckUrl.SubclassWindow(GetDlgItem(IDC_CON_CHECK));
	ConnCheckUrl.SetHyperLinkExtendedStyle(HLINK_COMMANDBUTTON | HLINK_UNDERLINEHOVER);
	// [- M.S.A] ConnCheckUrl.m_tip.AddTool(ConnCheckUrl, Text::toT("http://iceberg.leschat.net/forum/index.php?showtopic=207").c_str(), &ConnCheckUrl.m_rcLink, 1);
	BindCombo.Attach(GetDlgItem(IDC_BIND_ADDRESS));
	WinUtil::getAddresses(BindCombo);
	BindCombo.SetCurSel(BindCombo.FindString(0, Text::toT(SETTING(BIND_ADDRESS)).c_str()));
	
	if (BindCombo.GetCurSel() == -1)
	{
		BindCombo.AddString(Text::toT(SETTING(BIND_ADDRESS)).c_str());
		BindCombo.SetCurSel(BindCombo.FindString(0, Text::toT(SETTING(BIND_ADDRESS)).c_str()));
	}
	BindCombo.Detach();
	
	return TRUE;
}

void NetworkPage::fixControls()
{
	BOOL auto_detect = IsDlgButtonChecked(IDC_CONNECTION_DETECTION) == BST_CHECKED;
	BOOL direct = IsDlgButtonChecked(IDC_DIRECT) == BST_CHECKED;
	BOOL upnp = IsDlgButtonChecked(IDC_FIREWALL_UPNP) == BST_CHECKED;
	BOOL nat = IsDlgButtonChecked(IDC_FIREWALL_NAT) == BST_CHECKED;
	BOOL nat_traversal = IsDlgButtonChecked(IDC_NATT) == BST_CHECKED;
	BOOL dht = IsDlgButtonChecked(IDC_SETTINGS_USE_DHT) == BST_CHECKED;
	
#ifdef RIP_USE_CONNECTION_AUTODETECT
//	BOOL autodect = IsDlgButtonChecked(IDC_AUTODETECT) == BST_CHECKED;
	BOOL passive = IsDlgButtonChecked(IDC_FIREWALL_PASSIVE) == BST_CHECKED;
#else
	BOOL autodect = FALSE;
#endif
	
	::EnableWindow(GetDlgItem(IDC_DIRECT), !auto_detect);
	::EnableWindow(GetDlgItem(IDC_FIREWALL_UPNP), !auto_detect);
	::EnableWindow(GetDlgItem(IDC_FIREWALL_NAT), !auto_detect);
	::EnableWindow(GetDlgItem(IDC_FIREWALL_PASSIVE), !auto_detect);
	::EnableWindow(GetDlgItem(IDC_UPDATE_IP_DHT), dht/*!auto_detect*/); // [!] IRainman  if DHT is enable allow update IP from packets taked place firewall.
	::EnableWindow(GetDlgItem(IDC_SETTINGS_IP), !auto_detect);
	
	::EnableWindow(GetDlgItem(IDC_EXTERNAL_IP), !auto_detect && (direct || upnp || nat || nat_traversal));
	::EnableWindow(GetDlgItem(IDC_IP_GET_IP), !auto_detect && (upnp || nat)); //[+]PPA
	::EnableWindow(GetDlgItem(IDC_IP_URL_TEST), !auto_detect && (upnp || nat)); //[+ ~193-199]m.s.a
	::EnableWindow(GetDlgItem(IDC_OVERRIDE), !auto_detect && (direct || upnp || nat || nat_traversal));
#ifdef IRAINMAN_IP_AUTOUPDATE
	::EnableWindow(GetDlgItem(IDC_GETIP), (upnp || nat));
	::EnableWindow(GetDlgItem(IDC_IPUPDATE), (upnp || nat));
#endif
	BOOL ipupdate = (upnp || nat) && (IsDlgButtonChecked(IDC_IPUPDATE) == BST_CHECKED);
	::EnableWindow(GetDlgItem(IDC_SETTINGS_UPDATE_IP_INTERVAL), ipupdate);
	::EnableWindow(GetDlgItem(IDC_UPDATE_IP_INTERVAL), ipupdate);
	::EnableWindow(GetDlgItem(IDC_PORT_TCP), !auto_detect && (upnp || nat));
	::EnableWindow(GetDlgItem(IDC_PORT_UDP), !auto_detect && (upnp || nat));
	::EnableWindow(GetDlgItem(IDC_PORT_TLS), !auto_detect && (upnp || nat));
	::EnableWindow(GetDlgItem(IDC_CON_CHECK), !auto_detect && (upnp || nat));
	::EnableWindow(GetDlgItem(IDC_NATT), !auto_detect && !direct && !upnp && !nat); // for passive settings only
	
#ifdef RIP_USE_CONNECTION_AUTODETECT
	::EnableWindow(GetDlgItem(IDC_AUTODETECT), !passive);
#endif
}

LRESULT NetworkPage::onClickedActive(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	fixControls();
	return 0;
}

LRESULT NetworkPage::onGetIP(WORD /* wNotifyCode */, WORD /*wID*/, HWND /* hWndCtl */, BOOL& /* bHandled */)
{
	write();
	string aUrl = SETTING(URL_GET_IP);
	if (!Util::findSubString(aUrl, "http://"))
	{
		::EnableWindow(GetDlgItem(IDC_GETIP), false);
		c->addListener(this);
//[-]PPA    c->downloadFile("http://checkip.dyndns.org/");
		c->downloadFile(aUrl);
	}
	return 0;
}

LRESULT NetworkPage::onCheckConn(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{
	write();
	string aUrl = SETTING(URL_TEST_IP);
	if (!Util::findSubString(aUrl, "http://"))
	{
		WinUtil::openLink(Text::toT(aUrl) + _T("?port_IP=") + Text::toT(Util::toString(SETTING(TCP_PORT))) + _T("&port_PI=") + Text::toT(Util::toString(SETTING(UDP_PORT))) + _T("&ver=") + wstring(L_REVISION_NUM_STR));//Text::toT(Util::toString(BUILDID))); //[+ M.S.A]
	}
	return 0;
}

// [+] brain-ripper (rewriten by IRainman)
// Display warning if DHT turned on
LRESULT NetworkPage::onCheckDHTStats(WORD /* wNotifyCode */, WORD /*wID*/, HWND /* hWndCtl */, BOOL& /* bHandled */)
{
	if (IsDlgButtonChecked(IDC_SETTINGS_USE_DHT) == BST_CHECKED)
	{
		if (MessageBox(CTSTRING(DHT_WARNING), CTSTRING(WARNING), MB_ICONWARNING | MB_YESNO) != IDYES)
		{
			CheckDlgButton(IDC_SETTINGS_USE_DHT, BST_UNCHECKED);
		}
	}
	fixControls();
	return 0;
}
